// gcc -o test test.cpp -I /usr/include/mysql/ -L /usr/lib/mysql -l mysqlclient
#include "db_op.h"


MYSQL *g_conn; // mysql 连接
MYSQL_RES *g_res; // mysql 记录集
MYSQL_ROW g_row; // 字符串数组，mysql 记录行

#define MAX_BUF_SIZE 1024 // 缓冲区最大字节数


const char *g_host_name = "localhost";
const char *g_user_name = "root";
const char *g_password = "1";
const char *g_db_name = "Emtp";
const char *g_tb_name = "task";
const unsigned int g_db_port = 3306;

void print_mysql_error(const char *msg)   // 打印最后一次错误
{
    if (msg)
        printf("%s: %s\n", msg, mysql_error(g_conn));
    else
        puts(mysql_error(g_conn));
}

int executesql(const char * sql)
{
    /*query the database according the sql*/
    if (mysql_real_query(g_conn, sql, strlen(sql))) // 如果失败
        return -1; // 表示失败

    return 0; // 成功执行
}


int init_mysql()   // 初始化连接
{
    // init the database connection
    g_conn = mysql_init(NULL);

    /* connect the database */
    if(!mysql_real_connect(g_conn, g_host_name, g_user_name, g_password, g_db_name, g_db_port, NULL, 0)) // 如果失败
        return -1;

    // 是否连接已经可用
    executesql("set names utf8"); // 如果失败
    // return -1;
    return 0; // 返回成功
}


int update_db(TaskInfo *ti)
{
    if (init_mysql()){
        print_mysql_error(NULL);
        return 0;
    }
    char sql[MAX_BUF_SIZE]={0};
    char sqltmp[MAX_BUF_SIZE]={0};
    sprintf(sql,"INSERT INTO %s SET ",g_tb_name);

    if(ti->uid > 0) {
        sprintf(sqltmp,"uid=%lu, ",ti->uid);
        strcat(sql,sqltmp);
    }
    if(strlen(ti->fname) > 0){
        sprintf(sqltmp,"fname='%s', ",ti->fname);
        strcat(sql,sqltmp);
    }
    if(strlen(ti->path) > 0){
        sprintf(sqltmp,"path='%s', ",ti->path);
        strcat(sql,sqltmp);
    }
    if(ti->status >= 0){
        sprintf(sqltmp,"status=%d, ",ti->status);
        strcat(sql,sqltmp);
    }
    sql[strlen(sql)-2]=' ';
    strcat(sql,"ON DUPLICATE KEY UPDATE ");

    if(strlen(ti->path) > 0){
        sprintf(sqltmp,"path='%s', ",ti->path);
        strcat(sql,sqltmp);
    }
    if(ti->status >= 0){
        sprintf(sqltmp,"status=%d, ",ti->status);
        strcat(sql,sqltmp);
    }
    sql[strlen(sql)-2]='\0';
    //sprintf(sql,"select * from %s",g_tb_name);
    printf("%s\n",sql);
    if (executesql(sql)){ // 句末没有分号
        print_mysql_error(NULL);
        return 0;
    }

    mysql_store_result(g_conn); // 从服务器传送结果集至本地，mysql_use_result直接使用服务器上的记录集

    mysql_close(g_conn);
    return 1;
}

int select_db(char* cond,TaskInfo **ti){
    if (init_mysql()){
        print_mysql_error(NULL);
        return 0;
    }
    int i=0;
    char sql[MAX_BUF_SIZE]={0};

    sprintf(sql,"select * from %s where %s",g_tb_name,cond);

    if (executesql(sql)) // 句末没有分号
        print_mysql_error(NULL);

    g_res = mysql_store_result(g_conn); // 从服务器传送结果集至本地，mysql_use_result直接使用服务器上的记录集

    int iNum_rows = mysql_num_rows(g_res); // 得到记录的行数
    int iNum_fields = mysql_num_fields(g_res); // 得到记录的列数

    printf("共%d个记录，每个记录%d字段\n", iNum_rows, iNum_fields);

    // puts("id\tname\n");
    *ti=(TaskInfo*)malloc(sizeof(TaskInfo)*iNum_rows);
    if(ti==NULL){
        printf("Error to malloc memory\n");
        return 0;
    }
    while ((g_row=mysql_fetch_row(g_res))) // 打印结果集
    {
        //for(int j=0; j<iNum_fields; j++)
        //{
        //    printf("%s\t",g_row[i]);
        //}
        (*ti)[i].id=atoll(g_row[0]);
        (*ti)[i].uid=atoll(g_row[1]);
        strncpy((*ti)[i].fname,g_row[2],sizeof((*ti)[i].fname));
        strncpy((*ti)[i].path,g_row[3],sizeof((*ti)[i].path));
        (*ti)[i].status=atoi(g_row[4]);
        strncpy((*ti)[i].time,g_row[5],sizeof((*ti)[i].time));
        //printf("\n");
        i++;
    }
    mysql_close(g_conn);
    return iNum_rows;

}
//添加一个新任务
int add_task(TaskInfo *ti){
    update_db(ti);
    return 0;
}
//获取一个未执行的任务
int get_task(TaskInfo *ti){
    char* cond="status=0 limit 1";
    int size=select_db(cond,&ti);
    return 1;
}

//执行完一个任务后，需要设置标志为完成
int finish_task(TaskInfo *ti){
    if(ti==NULL) return -1;
    ti->status=1;
    update_db(ti);
    return 1;
}
//获取用户的所有信息
int get_file_list(uint64_t uid,TaskInfo** ti,int* size){
    char cond[MAX_BUF_SIZE]={0};
    sprintf(cond,"uid=%lu",uid);
    *size=select_db(cond,ti);
    return 0;
}


#if 0
int main(void)
{
    /* 
    TaskInfo *ti=NULL;
    int size=select_db(&ti);
    if(size<=0)
        return -1;

    for(int i=0;i<size;i++){
        printf("--------------%lu\n",ti[i].uid);
    }
    free(ti);
    */

   TaskInfo ti={
       0,
       1122,
       "111",
       "/var/",
       1
   };

    int size=update_db(&ti);
    return 0;
}
#endif